/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package DAO;

import DAO.exceptions.NonexistentEntityException;
import DAO.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import modelo.PersonaAtencion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import modelo.Roles;
import modelo.Usuario;

/**
 *
 * @author MANUEL
 */
public class RolesJpaController implements Serializable {

    public RolesJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Roles roles) throws PreexistingEntityException, Exception {
        if (roles.getPersonaAtencionCollection() == null) {
            roles.setPersonaAtencionCollection(new ArrayList<PersonaAtencion>());
        }
        if (roles.getUsuarioCollection() == null) {
            roles.setUsuarioCollection(new ArrayList<Usuario>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Collection<PersonaAtencion> attachedPersonaAtencionCollection = new ArrayList<PersonaAtencion>();
            for (PersonaAtencion personaAtencionCollectionPersonaAtencionToAttach : roles.getPersonaAtencionCollection()) {
                personaAtencionCollectionPersonaAtencionToAttach = em.getReference(personaAtencionCollectionPersonaAtencionToAttach.getClass(), personaAtencionCollectionPersonaAtencionToAttach.getNumAtencion());
                attachedPersonaAtencionCollection.add(personaAtencionCollectionPersonaAtencionToAttach);
            }
            roles.setPersonaAtencionCollection(attachedPersonaAtencionCollection);
            Collection<Usuario> attachedUsuarioCollection = new ArrayList<Usuario>();
            for (Usuario usuarioCollectionUsuarioToAttach : roles.getUsuarioCollection()) {
                usuarioCollectionUsuarioToAttach = em.getReference(usuarioCollectionUsuarioToAttach.getClass(), usuarioCollectionUsuarioToAttach.getNumUsuario());
                attachedUsuarioCollection.add(usuarioCollectionUsuarioToAttach);
            }
            roles.setUsuarioCollection(attachedUsuarioCollection);
            em.persist(roles);
            for (PersonaAtencion personaAtencionCollectionPersonaAtencion : roles.getPersonaAtencionCollection()) {
                Roles oldRolNumRolOfPersonaAtencionCollectionPersonaAtencion = personaAtencionCollectionPersonaAtencion.getRolNumRol();
                personaAtencionCollectionPersonaAtencion.setRolNumRol(roles);
                personaAtencionCollectionPersonaAtencion = em.merge(personaAtencionCollectionPersonaAtencion);
                if (oldRolNumRolOfPersonaAtencionCollectionPersonaAtencion != null) {
                    oldRolNumRolOfPersonaAtencionCollectionPersonaAtencion.getPersonaAtencionCollection().remove(personaAtencionCollectionPersonaAtencion);
                    oldRolNumRolOfPersonaAtencionCollectionPersonaAtencion = em.merge(oldRolNumRolOfPersonaAtencionCollectionPersonaAtencion);
                }
            }
            for (Usuario usuarioCollectionUsuario : roles.getUsuarioCollection()) {
                Roles oldRolNumRolOfUsuarioCollectionUsuario = usuarioCollectionUsuario.getRolNumRol();
                usuarioCollectionUsuario.setRolNumRol(roles);
                usuarioCollectionUsuario = em.merge(usuarioCollectionUsuario);
                if (oldRolNumRolOfUsuarioCollectionUsuario != null) {
                    oldRolNumRolOfUsuarioCollectionUsuario.getUsuarioCollection().remove(usuarioCollectionUsuario);
                    oldRolNumRolOfUsuarioCollectionUsuario = em.merge(oldRolNumRolOfUsuarioCollectionUsuario);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findRoles(roles.getNumRol()) != null) {
                throw new PreexistingEntityException("Roles " + roles + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Roles roles) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Roles persistentRoles = em.find(Roles.class, roles.getNumRol());
            Collection<PersonaAtencion> personaAtencionCollectionOld = persistentRoles.getPersonaAtencionCollection();
            Collection<PersonaAtencion> personaAtencionCollectionNew = roles.getPersonaAtencionCollection();
            Collection<Usuario> usuarioCollectionOld = persistentRoles.getUsuarioCollection();
            Collection<Usuario> usuarioCollectionNew = roles.getUsuarioCollection();
            Collection<PersonaAtencion> attachedPersonaAtencionCollectionNew = new ArrayList<PersonaAtencion>();
            for (PersonaAtencion personaAtencionCollectionNewPersonaAtencionToAttach : personaAtencionCollectionNew) {
                personaAtencionCollectionNewPersonaAtencionToAttach = em.getReference(personaAtencionCollectionNewPersonaAtencionToAttach.getClass(), personaAtencionCollectionNewPersonaAtencionToAttach.getNumAtencion());
                attachedPersonaAtencionCollectionNew.add(personaAtencionCollectionNewPersonaAtencionToAttach);
            }
            personaAtencionCollectionNew = attachedPersonaAtencionCollectionNew;
            roles.setPersonaAtencionCollection(personaAtencionCollectionNew);
            Collection<Usuario> attachedUsuarioCollectionNew = new ArrayList<Usuario>();
            for (Usuario usuarioCollectionNewUsuarioToAttach : usuarioCollectionNew) {
                usuarioCollectionNewUsuarioToAttach = em.getReference(usuarioCollectionNewUsuarioToAttach.getClass(), usuarioCollectionNewUsuarioToAttach.getNumUsuario());
                attachedUsuarioCollectionNew.add(usuarioCollectionNewUsuarioToAttach);
            }
            usuarioCollectionNew = attachedUsuarioCollectionNew;
            roles.setUsuarioCollection(usuarioCollectionNew);
            roles = em.merge(roles);
            for (PersonaAtencion personaAtencionCollectionOldPersonaAtencion : personaAtencionCollectionOld) {
                if (!personaAtencionCollectionNew.contains(personaAtencionCollectionOldPersonaAtencion)) {
                    personaAtencionCollectionOldPersonaAtencion.setRolNumRol(null);
                    personaAtencionCollectionOldPersonaAtencion = em.merge(personaAtencionCollectionOldPersonaAtencion);
                }
            }
            for (PersonaAtencion personaAtencionCollectionNewPersonaAtencion : personaAtencionCollectionNew) {
                if (!personaAtencionCollectionOld.contains(personaAtencionCollectionNewPersonaAtencion)) {
                    Roles oldRolNumRolOfPersonaAtencionCollectionNewPersonaAtencion = personaAtencionCollectionNewPersonaAtencion.getRolNumRol();
                    personaAtencionCollectionNewPersonaAtencion.setRolNumRol(roles);
                    personaAtencionCollectionNewPersonaAtencion = em.merge(personaAtencionCollectionNewPersonaAtencion);
                    if (oldRolNumRolOfPersonaAtencionCollectionNewPersonaAtencion != null && !oldRolNumRolOfPersonaAtencionCollectionNewPersonaAtencion.equals(roles)) {
                        oldRolNumRolOfPersonaAtencionCollectionNewPersonaAtencion.getPersonaAtencionCollection().remove(personaAtencionCollectionNewPersonaAtencion);
                        oldRolNumRolOfPersonaAtencionCollectionNewPersonaAtencion = em.merge(oldRolNumRolOfPersonaAtencionCollectionNewPersonaAtencion);
                    }
                }
            }
            for (Usuario usuarioCollectionOldUsuario : usuarioCollectionOld) {
                if (!usuarioCollectionNew.contains(usuarioCollectionOldUsuario)) {
                    usuarioCollectionOldUsuario.setRolNumRol(null);
                    usuarioCollectionOldUsuario = em.merge(usuarioCollectionOldUsuario);
                }
            }
            for (Usuario usuarioCollectionNewUsuario : usuarioCollectionNew) {
                if (!usuarioCollectionOld.contains(usuarioCollectionNewUsuario)) {
                    Roles oldRolNumRolOfUsuarioCollectionNewUsuario = usuarioCollectionNewUsuario.getRolNumRol();
                    usuarioCollectionNewUsuario.setRolNumRol(roles);
                    usuarioCollectionNewUsuario = em.merge(usuarioCollectionNewUsuario);
                    if (oldRolNumRolOfUsuarioCollectionNewUsuario != null && !oldRolNumRolOfUsuarioCollectionNewUsuario.equals(roles)) {
                        oldRolNumRolOfUsuarioCollectionNewUsuario.getUsuarioCollection().remove(usuarioCollectionNewUsuario);
                        oldRolNumRolOfUsuarioCollectionNewUsuario = em.merge(oldRolNumRolOfUsuarioCollectionNewUsuario);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = roles.getNumRol();
                if (findRoles(id) == null) {
                    throw new NonexistentEntityException("The roles with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Roles roles;
            try {
                roles = em.getReference(Roles.class, id);
                roles.getNumRol();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The roles with id " + id + " no longer exists.", enfe);
            }
            Collection<PersonaAtencion> personaAtencionCollection = roles.getPersonaAtencionCollection();
            for (PersonaAtencion personaAtencionCollectionPersonaAtencion : personaAtencionCollection) {
                personaAtencionCollectionPersonaAtencion.setRolNumRol(null);
                personaAtencionCollectionPersonaAtencion = em.merge(personaAtencionCollectionPersonaAtencion);
            }
            Collection<Usuario> usuarioCollection = roles.getUsuarioCollection();
            for (Usuario usuarioCollectionUsuario : usuarioCollection) {
                usuarioCollectionUsuario.setRolNumRol(null);
                usuarioCollectionUsuario = em.merge(usuarioCollectionUsuario);
            }
            em.remove(roles);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Roles> findRolesEntities() {
        return findRolesEntities(true, -1, -1);
    }

    public List<Roles> findRolesEntities(int maxResults, int firstResult) {
        return findRolesEntities(false, maxResults, firstResult);
    }

    private List<Roles> findRolesEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Roles.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Roles findRoles(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Roles.class, id);
        } finally {
            em.close();
        }
    }

    public int getRolesCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Roles> rt = cq.from(Roles.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
